package com.baiduspring.web.search;

import com.baiduspring.function.elasticsearch.ElasticsearchHandle;
import com.baiduspring.function.elasticsearch.operation.QueryInput;
import com.baiduspring.service.specialcolumn.SpecialColumnIndexEnum;
import com.baiduspring.service.user.UserService;
import com.baiduspring.utils.elasticsearch.ElasticSearchUtils;
import com.baiduspring.utils.elasticsearch.ScriptTextEnum;
import com.baiduspring.vo.ResultsVO;
import com.baiduspring.web.user.LoginStatus;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.hankcs.hanlp.HanLP;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 详情页控制器
 *
 * @author xiongyan
 */
@RestController
@Scope("prototype")
@RequestMapping("/detail")
@Slf4j
public class DetailsController {
    @Resource
    private UserService userService;

    /**
     * 进入文章详情页
     *
     * @param request 参数
     * @param account 参数
     * @param uriMark 参数
     * @return 返回视图
     */
    @GetMapping("/{account}/{uriMark}")
    public ModelAndView detail(HttpServletRequest request, @PathVariable("account") Long account, @PathVariable("uriMark") Long uriMark) {
        ModelAndView view = new ModelAndView("special-column/blog_detail");

        LoginStatus.status(request, view);

        QueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .must(QueryBuilders.matchPhraseQuery("authorAccount", account))
                .must(QueryBuilders.matchPhraseQuery("uriMark", uriMark));

        String[] indies = {SpecialColumnIndexEnum.SPECIAL_COLUMN_BLOG_INDEX.getValue()};
        String[] types = {SpecialColumnIndexEnum.SPECIAL_COLUMN_BLOG_TYPE.getValue()};

        Map<String, Class> outputFields = Maps.newHashMap();
        outputFields.put("id", String.class);
        outputFields.put("title", String.class);
        outputFields.put("orig", Integer.class);
        outputFields.put("label", String.class);
        outputFields.put("content", String.class);
        outputFields.put("authorAccount", Long.class);
        outputFields.put("readNum", Integer.class);
        outputFields.put("collectNum", Integer.class);
        outputFields.put("likesNum", Integer.class);
        outputFields.put("updateDate", Long.class);

        QueryInput input = new QueryInput();
        input.setIndices(indies);
        input.setTypes(types);
        input.setOutputFields(outputFields);

        ElasticSearchUtils.multipleFieldValueQuery(input, queryBuilder, ResultsVO.class, output -> {
            for (Object o : output.getResults()) {
                ResultsVO vo = (ResultsVO) o;
                userService.getByAccount(vo.getAuthorAccount()).ifPresent(user -> vo.setUser(user));
                //更新阅读量
                ElasticsearchHandle.instance().scriptUpdateFieldValue(indies[0], types[0], vo.getId(), ScriptTextEnum.READ_NUM.getScript());
                vo.setReadNum(Objects.nonNull(vo.getReadNum()) ? vo.getReadNum() + 1 : 1);
                view.addObject("data", vo);

                interrestsBlogs(view, indies, types, vo);
            }
        });

        return view;
    }

    private void interrestsBlogs(ModelAndView view, String[] indies, String[] types, ResultsVO vo) {
        List<String> keywords = HanLP.extractKeyword(vo.getTitle(), 2);
        StringBuilder keywordsBuilder = new StringBuilder();
        keywords.forEach(s -> keywordsBuilder.append(s));

        QueryInput inputByKeywords = new QueryInput();
        String[] filterFields = {
                "title",
                "contentTxt"
        };
        inputByKeywords.setFilterFields(filterFields)
                .setKeywords(keywordsBuilder.toString())
                .setCurrentPage(0)
                .setPageSize(5);

        Map<String, Class> fields = Maps.newHashMap();
        fields.put("title", String.class);
        fields.put("authorAccount", Long.class);
        fields.put("readNum", Integer.class);
        fields.put("collectNum", Integer.class);
        fields.put("uriMark", Long.class);

        inputByKeywords.setIndices(indies)
                .setTypes(types)
                .setOutputFields(fields);

        ElasticSearchUtils.query(inputByKeywords, false, ResultsVO.class,
                outs -> {

                    List<ResultsVO> resList = Lists.newArrayList();
                    for (Object o : outs.getResults()) {
                        ResultsVO resultsVO = (ResultsVO)o;
                        if (!resultsVO.getId().equals(vo.getId())) {
                            resList.add(resultsVO);
                        }
                    }
                    view.addObject("interests", resList);
                    System.out.println();
                });
    }
}
